import React, { memo, useEffect, useState } from "react";
import { getServiceInfo } from "@common/envOverviewApi/doc";
import { ServiceInitialState } from "@model";
import { Collapse, Empty, message, Modal, Spin } from "antd";
import Highlight from "react-highlight";
import "highlight.js/styles/vs2015.css";
import request from "@pkgs/request";
import api from "@common/api";
import "./style.less";
import { Link } from "react-router-dom";

type Props = {
  nodeName: string;
};

/**
 * @func 应用信息页面组件
 * @param props
 * @returns React.FC
 */
const Service: React.FC<Props> = (props) => {
  const [data, setData] = useState(ServiceInitialState);

  const { nodeName } = props;
  const { Panel } = Collapse;

  useEffect(() => {
    getServiceInfoData();
  }, []);

  const getServiceInfoData = async () => {
    try {
      const json = await getServiceInfo(nodeName);
      setData(json);
    } catch (err) {}
  };

  return (
    <div className="service-wrapper">
      {data.found && data._source.service ? (
        <Collapse defaultActiveKey={["0"]}>
          {data._source.service.map((item, index) => (
            <Panel
              header={
                <span style={{ color: item.checkstatus ? "green" : "red" }}>
                  {item.name}
                </span>
              }
              key={index}
              extra={
                item.checkstatus ? (
                  <span style={{ color: "green" }}>正常</span>
                ) : (
                  <span style={{ color: "red" }}>异常</span>
                )
              }
            >
              <div className="content">
                <p>应用名称:</p>
                <span>{item.name}</span>
              </div>
              <div className="content">
                <p>校验状态:</p>
                <span>{item.checkstatus ? "正常" : "异常"}</span>
              </div>
              <div className="content">
                <p>配置ID:</p>
                {item.checkid !== null && item.checkid !== "" ? (
                  <span>
                    <Link
                      to={{
                        pathname: `/collect/modify/service/${item.checkid}`,
                      }}
                    >
                      {item.checkid}
                    </Link>
                  </span>
                ) : (
                  <span>null</span>
                )}
              </div>
              <div className="content">
                <p>数据:</p>
                <span>{item.data}</span>
              </div>
              <div className="content">
                <p>路径:</p>
                <span>{item.path}</span>
              </div>
              <div className="content">
                <p>配置:</p>
                <span>{item.conf}</span>
              </div>
              <div className="content">
                <p>程序:</p>
                <span>{item.bin}</span>
              </div>
              <div className="content">
                <p>进程:</p>
                <span>{item.procnum}</span>
              </div>
              <div className="content-procinfo">
                <p>进程详情:</p>
                {item.procinfo.length ? (
                  <Highlight>
                    {item.procinfo.map((item, index) => (
                      <div key={index}>{item}</div>
                    ))}
                  </Highlight>
                ) : (
                  "暂无进程详情!"
                )}
              </div>
              <div className="content-procinfo">
                <p>端口:</p>
                {item.port.length
                  ? item.port.map((item, index) => (
                      <div key={index}>{item}</div>
                    ))
                  : "暂无端口信息!"}
              </div>
              <div className="content">
                <p>进程MD5:</p>
                <span>{item.md5}</span>
              </div>
              <div className="content-version">
                <p>进程版本:</p>
                <Highlight>{item.version}</Highlight>
              </div>
              <div className="content">
                <p>配置变化数量:</p>
                {item.changenum !== "null" ? (
                  <>
                    <span>{item.changenum} 个&nbsp;</span>
                    {item.changenum !== 0 && (
                      <Model checkid={item.checkid} nodeName={nodeName} />
                    )}
                  </>
                ) : (
                  <span>null</span>
                )}
              </div>
              <div className="content">
                <p>检查时间:</p>
                <span>{item.time}</span>
              </div>
              <div className="content">
                <p>检查详情:</p>
              </div>
              <Highlight>{item.output ? item.output : 'null'}</Highlight>
            </Panel>
          ))}
        </Collapse>
      ) : (
        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
      )}
    </div>
  );
};

/**
 * @func 弹窗&下载函数
 */
const Model = ({ checkid, nodeName }: any) => {
  const [loading, setLoading] = useState(false);
  const [visible, setVisible] = useState(false);
  const [changenumData, setChangenumData] = useState();

  const getChangenumData = (checkid: number) => {
    setLoading(true);
    request(`${api.env}/${nodeName}/${checkid}/md5diff/content`, { signal })
      .then((response) => {
        setChangenumData(response);
        setVisible(true);
      })
      .catch((err) => {
        message.error(err);
      });
    setLoading(false);
  };

  const info = async (checkid: any) => {
    await getChangenumData(checkid);
  };

  // NOTE 取消请求，这里数据量有可能会较大造成长时间等待，提供了取消请求和下载到本地
  const controller = new AbortController();
  const signal = controller.signal;
  /**
   * @func 详情下载函数
   * @param param0 数据
   * @param param1 下载文件名
   * @param param2 格式
   */
  const downloadFile = ({
    data,
    fileName,
    fileType,
  }: {
    data: string;
    fileName: string;
    fileType: string;
  }) => {
    const blob = new Blob([data], { type: fileType });
    const a = document.createElement("a");
    a.download = fileName;
    a.href = window.URL.createObjectURL(blob);
    const clickEvt = new MouseEvent("click", {
      view: window,
      bubbles: true,
      cancelable: true,
    });
    a.dispatchEvent(clickEvt);
    a.remove();
  };

  const download = (checkid: any) => {
    request(`${api.env}/${nodeName}/${checkid}/md5diff/file`, { signal })
      .then((res) => {
        downloadFile({
          data: res,
          fileName: "changenum.json",
          fileType: "text/json",
        });
      })
      .catch((err) => {
        message.error(err);
      });
  };

  const handleOk = () => {
    controller.abort();
    setVisible(false);
  };

  const handleCancel = () => {
    setVisible(false);
  };

  return (
    <>
      <a onClick={() => info(checkid)}>详情</a>
      &nbsp;
      <a onClick={() => download(checkid)}>下载</a>
      <Modal
        title="配置变化数量详情"
        visible={visible}
        onOk={handleOk}
        onCancel={handleCancel}
        width="60%"
      >
        <div className="content-modal">
          <Spin spinning={loading}></Spin>
          <Highlight>{changenumData}</Highlight>
        </div>
      </Modal>
    </>
  );
};

export default memo(Service);
